package com.wutianyi;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;

import com.wutianyi.jackson.User;

public abstract class TypeReference<T>
{
    private final Type type;
    private volatile Constructor<?> constructor;

    protected TypeReference()
    {
        Type superclass = getClass().getGenericSuperclass();
        if (superclass instanceof Class)
        {
            throw new RuntimeException();
        }
        this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
    }

    public T newInstance() throws IllegalArgumentException, InstantiationException, IllegalAccessException,
            InvocationTargetException, SecurityException, NoSuchMethodException
    {
        if (constructor == null)
        {
            Class<?> rawType = type instanceof Class<?> ? (Class<?>) type : (Class<?>) ((ParameterizedType) type)
                    .getRawType();
            constructor = rawType.getConstructor();
        }
        return (T) constructor.newInstance();
    }

    public Type getType()
    {
        return this.type;
    }

    public boolean equals(Object o)
    {
        return (o instanceof TypeReference) ? ((TypeReference) o).getType().equals(this.getType()) : false;
    }

    public int hashCode()
    {
        return this.getType().hashCode();
    }

    public static void main(String[] args)
    {
        // TypeReference<HashMap<String, User>> type = new
        // TypeReference<HashMap<String, User>>();
    }
}
